home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / basic / mildred / lha / ilbmviewer.lha / Chunky.ascii next >
Text File  |  1999-03-03  |  12KB  |  356 lines

  1.  
  2. ; Chunky routines
  3.  
  4. ;ILBM-loader constants
  5. #ILBM_FileHandle=0
  6. #FORMid=$464F524D ; "FORM"
  7. #ILBMid=$494C424D ; "ILBM"
  8. #BMHDid=$424D4844 ; "BMHD"
  9. #CMAPid=$434D4150 ; "CMAP"
  10. #CAMGid=$43414D47 ; "CAMG"
  11. #BODYid=$424F4459 ; "BODY"
  12.  
  13. NEWTYPE.BMHD
  14.   Width.w
  15.   Height.w
  16.   X.w
  17.   Y.w
  18.   Planes.b
  19.   Masking.b
  20.   Compression.b
  21.   Pad1.b
  22.   Transparent.w
  23.   XAspect.b
  24.   YAaspect.b
  25.   SourceWidth.w
  26.   SourceHeight.w
  27. End NEWTYPE
  28.  
  29. NEWTYPE._RGBComponents
  30.   _Red.l
  31.   _Green.l
  32.   _Blue.l
  33. End NEWTYPE
  34.  
  35. NEWTYPE._PaletteData
  36.   NumCols.w
  37.   Zero.w
  38.   _RGBs._RGBComponents[256]
  39.   Zero2.l
  40. End NEWTYPE
  41.  
  42. Statement ChunkyClearscreen4{ChunkyBuf.l,BufHeight.w,OpWidth.w,DestWidth.w,Value.l}
  43. ;Clears the rightmost 4-pixel-width column in the chunky buffer to Value.l
  44. ;Covers up the longword clip/wrap buffer. Column is rightmost to OpWidth, DestWidth supplies modulo
  45.   MOVE.l  d0,a0 ; Chunky output
  46.   AND.l   #$FFFF,d1 ; Only word
  47.   SUBQ.l  #1,d1 ; Loopcounter
  48.   AND.l   #$FFFF,d3 ; Modulo
  49.   SUBQ.l  #4,d3 ; Modulo-4 to accomodate move.l
  50.   AND.l   #$FFFF,d2 ; Only word
  51.   SUBQ.l  #4,d2 ; OpWidth-4, x start position
  52.   ADD.l   d2,a0 ; Source position
  53. ChunkyClear4
  54.   MOVE.l  d4,(a0)+ ; Clear 4 pixels
  55.   ADD.l   d3,a0 ; Dest Modulo
  56.   DBRA    d1,ChunkyClear4
  57.   AsmExit
  58. End Statement
  59.  
  60. Statement ChunkyClearscreen32{ChunkyBuf.l,BufHeight.w,Value.l,Width.w}
  61. ;Clears chunky screen, Width*BufHeight pixels (Width multiples of 32!)
  62.   MOVE.l  a3,-(a7)
  63.   MOVE.l  d0,a0 ; Chunky output
  64.   MOVE.l  d2,d0 ; Get value
  65.   AND.l   #$FFFF,d3 ; Only word
  66.   MOVE.l  d3,d2 ; Width
  67.   AND.l   #$FFFF,d1 ; Only word
  68.   MULU    d1,d2 ; Size in bytes
  69.   ADD.l   d2,a0 ; To end of buffer
  70.   SUBQ.l  #1,d1 ; Init YLoop
  71.   EXG.l   d0,d3 ; 1
  72.   MOVE.l  d3,d4 ; 2
  73.   MOVE.l  d3,d5 ; 3
  74.   MOVE.l  d3,d6 ; 4
  75.   MOVE.l  d3,d7 ; 5
  76.   MOVE.l  d3,a1 ; 6
  77.   MOVE.l  d3,a2 ; 7
  78.   MOVE.l  d3,a3 ; 8 longwords = 32 pixels
  79.   LSR.w   #2+3,d0 ; Width in longwords (2=2^2=4=longwords, 3=2^3=8=groups of 8 longwords)
  80.   SUBQ.l  #1,d0 ; Xloopcounter
  81. ChunkyClrLoopY
  82.     MOVE.l  d0,d2 ; Init XLoop
  83. ChunkyClrLoopX
  84.       MOVEM.l d3-d7/a1-a3,-(a0) ; Clear 32 pixels
  85.       DBRA    d2,ChunkyClrLoopX
  86.     DBRA    d1,ChunkyClrLoopY
  87.   MOVE.l  (a7)+,a3
  88.   AsmExit
  89. End Statement
  90.  
  91. Statement ChunkyCopy16{ChunkyBufA.l,ChunkyBufB.l,BufHeight.w,CPU.b,OpWidth.w,DestWidth.w}
  92. ;Copies one chunky screen to another, Width*BufHeight pixels (Width multiples of 16!)
  93. ;Seperate routines for 040+ (move16) and 030- (movem)
  94. ;Width of source buffer and dest buffer will be the same and use the same modulo but OpWidth can be narrower
  95.   MOVE.l  d0,a0   ; Chunky source
  96.   MOVE.l  d1,a1   ; Chunky destination
  97.   MOVE.w  d2,d0   ; Height
  98.   AND.l   #$FFFF,d0 ; Only word
  99.   SUBQ.l  #1,d0   ; d0=YLoop
  100.   AND.l   #$FFFF,d4 ; Only word
  101.   AND.l   #$FFFF,d5 ; Only word
  102.   SUB.l   d4,d5   ; Dest modulo
  103.   LSR.w   #2+2,d4   ; Longwords (2=2^2=4=longwords, 2=2^2=4=groups of 4 longwords
  104.   SUBQ.l  #1,d4   ; loop
  105.   MOVE.l  d4,d1   ; d1=XLoop
  106.   MOVE.l  d5,d2   ; d2=Dest Modulo
  107.   CMP.b   #4,d3   ; 040+?
  108.   BEQ     ChunkyCopy040 ; Yes, do move16's
  109.   ADD.l   #16,a1
  110. ChunkyCopy030
  111. ChunkyCopy030y
  112.     MOVE.l  d1,d3 ; d3=Xloop
  113. ChunkyCopy030x
  114.       MOVEM.l (a0)+,d4-d7
  115.       MOVEM.l d4-d7,-(a1) ; 16 pixels
  116.       ADD.l   #32,a1
  117.       DBRA    d3,ChunkyCopy030x
  118.     ADD.l   d2,a0   ; Source modulo
  119.     ADD.l   d2,a1   ; Dest modulo
  120.     DBRA    d0,ChunkyCopy030y
  121.   AsmExit
  122. ChunkyCopy040
  123. ChunkyCopy040y
  124.     MOVE.l  d1,d3 ; d3=Xloop
  125. ChunkyCopy040x
  126.       Dc.l    $F6209000 ; move16 (a0)+,(a1)+ ; 16 bytes
  127.       DBRA    d3,ChunkyCopy040x
  128.     ADD.l   d2,a0   ; Source modulo
  129.     ADD.l   d2,a1   ; Dest modulo
  130.     DBRA    d0,ChunkyCopy040y
  131.   AsmExit
  132. End Statement
  133.  
  134. Statement ILBMP2C{Src.l,Dest.l,ChunkyBytes.l,PlanarBytes.l}
  135. ;Convert an interleaved planar buffer to chunky (eight-pass)
  136. ;Bytes must be even (nearest 16 pixels)
  137.   MOVE.l d1,a1        ; Dest
  138.   MOVE.l d2,a2        ; End address
  139.   MOVE.l d3,d2        ; Plane byte width (for plane selection)
  140.   MOVEQ.l #7,d3       ; Planes-1
  141.   ADD.l a1,a2         ; Point to end
  142. P2Cplaneloop
  143.   MOVE.l  d1,a1       ; Start of dest
  144.   MOVEQ.l #7,d6       ; Temp
  145.   SUB.l   d3,d6       ; Reverse plane number (start at 0)
  146.   MOVE.l  d0,a0       ; Source
  147.   MOVE.l  d2,d7       ; Get size
  148.   MULU    d6,d7       ; Offset
  149.   ADD.l   d7,a0       ; Point
  150. P2Cwordloop
  151.     MOVE.w (a0)+,d4   ; Get planar word
  152.     MOVE.w #15,d5     ; bit loopcounter
  153. P2Cbitloop
  154.       LSL.w #1,d4     ; Put leftmost bit into eXtend flag
  155.       MOVE.b (a1),d6  ; Get existing destination byte
  156.       ROXR.b #1,d6    ; Rotate it right, bringing in the eXtend flag on the left
  157.       MOVE.b d6,(a1)+ ; Update the destination pixel
  158.       DBRA d5,P2Cbitloop ; next planar bit (and next chunky pixel)
  159.     CMP.l a1,a2       ; At the end of a line of chunky pixels yet?
  160.     BGT P2Cwordloop   ; Yes, so do the next 16 pixels of planar (word)
  161.     DBRA d3,P2Cplaneloop ; Next plane
  162.   AsmExit
  163. End Statement
  164.  
  165. Statement ILBMReadPal{PalNum.w,Cols.w}
  166. ;Grab a palette from the ILBM file into a palette object
  167.   InitPalette PalNum,Cols
  168.   *PalTmp.palette=Addr Palette(PalNum)
  169.   *PalDat._PaletteData=*PalTmp\_pdata
  170.   R.l=0
  171.   G.l=0
  172.   B.l=0
  173.   For CLoop.w=0 To Cols-1
  174.     ReadMem #ILBM_FileHandle,&R+3,1
  175.     ReadMem #ILBM_FileHandle,&G+3,1
  176.     ReadMem #ILBM_FileHandle,&B+3,1
  177.     *RGBTmp._RGBComponents=*PalDat\_RGBs[CLoop]
  178.     *RGBTmp\_Red=(((((R LSL 8)|R) LSL 8)| R)LSL 8)|R
  179.     *RGBTmp\_Green=(((((G LSL 8)|G) LSL 8)| G)LSL 8)|G
  180.     *RGBTmp\_Blue=(((((B LSL 8)|B) LSL 8)| B)LSL 8)|B
  181.   Next CLoop
  182. End Statement
  183.  
  184. Function.b LoadLandILBM{FName$,PalNum.w,CWidth.w,CHeight.w,CDest.l,CDest2.l}
  185. ;ILBM-picture land-loader
  186.   SHARED LandWidth ; Now needed
  187.   SHARED ILBMHAM.l,IsAGA.b
  188.   If Exists(FName$)
  189.     suc=OpenFile(#ILBM_FileHandle,FName$)
  190.     If suc=False Then Function Return False
  191.   Else
  192.     Function Return False
  193.   EndIf
  194.   FormCheck.l=0
  195.   ReadMem #ILBM_FileHandle,&FormCheck,4
  196.   If FormCheck<>#FORMid Then Function Return False
  197.   FormSize.l=0
  198.   TempLong.l=0
  199.   ChunkSize.l=0
  200.   ReadMem #ILBM_FileHandle,&FormSize,4
  201.   ReadMem #ILBM_FileHandle,&TempLong,4
  202.   FilePos.l=12
  203.   If PalNum=-1 Then Complete.w=2 Else Complete.w=0
  204.   If TempLong=#ILBMid
  205.     While ((FilePos<FormSize)&(NOT(Eof(#ILBM_FileHandle))))&(Complete<3)
  206.       ReadMem #ILBM_FileHandle,&TempLong,4
  207.       ReadMem #ILBM_FileHandle,&ChunkSize,4
  208.       FilePos+8
  209.       ChunkSize+(ChunkSize&1)
  210.       Select TempLong
  211.         Case #CMAPid
  212.           ;Colourmap chunk
  213.           If PalNum>-1 Then ILBMReadPal{PalNum,ChunkSize/3}
  214.         Case #BMHDid
  215.           ;BitmapHeader chunk
  216.           If ChunkSize>=SizeOf.BMHD
  217.             TmpBmHd.BMHD\Width=0
  218.             ReadMem #ILBM_FileHandle,&TmpBmHd,SizeOf.BMHD
  219.             If TmpBmHd\Planes>8
  220.               Complete=4 ; Not allowed 24-bit iff's
  221.             Else
  222.               EBWidth.w=TmpBmHd\Width
  223.               If EBWidth>(EBWidth AND $FFFFFFF0) Then EBWidth=(EBWidth+16) AND $FFFFFFF0 ; Handle uneven byte widths
  224.               EBWidth.w=EBWidth LSR 3
  225.               If AvailMem_(#MEMF_FAST)<EBWidth*8 Then Function Return False
  226.               BufAdr.l=AllocMem(EBWidth*8,$10000) ; One interleaved line (up to 8 planes)
  227.               If BufAdr=0 Then Complete=4
  228.             EndIf
  229.           EndIf
  230.         Case #CAMGid
  231.           ;Amigamodes chunk
  232.           CAMGmodes.l=0
  233.           ReadMem #ILBM_FileHandle,&CAMGmodes,4
  234.           If ((CAMGmodes AND $00000800)>0) Then ILBMHAM.l=$800
  235.         Case #BODYid
  236.           ;Body chunk
  237.           If BufAdr<>0
  238.             If TmpBmHd\Compression=0
  239.               For YLoop.w=0 To TmpBmHd\Height-1
  240.                 For PLoop.w=0 To TmpBmHd\Planes-1
  241.                   PlanePtr.l=BufAdr+(PLoop*EBWidth)
  242.                   ReadMem #ILBM_FileHandle,PlanePtr,EBWidth
  243.                 Next PLoop
  244.                 If YLoop<CHeight-1
  245.                   out.l=LandWidth*YLoop
  246.                   ILBMP2C{BufAdr,CDest+out,CWidth,EBWidth} ; Main chunky output
  247.                   If CDest2<>0 Then ILBMP2C{BufAdr,CDest2+out,CWidth,EBWidth} ; Duplicate
  248.                   For PPos.l=BufAdr To BufAdr+(EBWidth*8)-1 Step 2
  249.                     NPokeW PPos,0
  250.                   Next PPos
  251.                 EndIf
  252.               Next YLoop
  253.             Else
  254.               PStep.l=0
  255.               GfxCur.b=0
  256.               GfxLen.w=0
  257.               GfxByte.b=0
  258.               PLoop.w=0
  259.               YLoop.w=0
  260.               PlanePtr.l=BufAdr
  261.               While YLoop<TmpBmHd\Height
  262.                 ReadMem #ILBM_FileHandle,&GfxCur,1
  263.                 If GfxCur>=0
  264.                   GfxLen=GfxCur+1
  265.                   ReadMem #ILBM_FileHandle,PlanePtr,GfxLen
  266.                   PlanePtr+GfxLen
  267.                   PStep+GfxLen
  268.                 Else
  269.                   If GfxCur>-128
  270.                     GfxLen=-GfxCur+1
  271.                     ReadMem #ILBM_FileHandle,&GfxByte,1
  272.                     PStep+GfxLen
  273.                     For BLoop.w=0 To GfxLen-1
  274.                       NPokeB PlanePtr,GfxByte
  275.                       PlanePtr+1
  276.                     Next BLoop
  277.                   EndIf
  278.                 EndIf
  279.                 If PStep>=EBWidth
  280.                   PLoop+1
  281.                   If PLoop=TmpBmHd\Planes
  282.                     If YLoop<CHeight-1
  283.                       out.l=LandWidth*YLoop
  284.                       ILBMP2C{BufAdr,CDest+out,CWidth,EBWidth} ; Main chunky output
  285.                       If CDest2<>0 Then ILBMP2C{BufAdr,CDest2+out,CWidth,EBWidth} ; Duplicate
  286.                       For PPos.l=BufAdr To BufAdr+(EBWidth*8)-1 Step 2
  287.                         NPokeW PPos,0
  288.                       Next PPos
  289.                     EndIf
  290.                     YLoop+1
  291.                     PLoop=0
  292.                   EndIf
  293.                   PlanePtr=BufAdr+(EBWidth*PLoop)
  294.                   PStep=0
  295.                 EndIf
  296.               Wend
  297.             EndIf
  298.             Complete=3
  299.           Else
  300.             Complete=4
  301.           EndIf
  302.       End Select
  303.       FilePos+ChunkSize
  304.       FileSeek #ILBM_FileHandle,FilePos
  305.     Wend
  306.   EndIf
  307.   CloseFile #ILBM_FileHandle
  308.   If BufAdr<>0 Then FreeMem BufAdr,EBWidth*8
  309.   If Complete=3
  310.     Function Return True
  311.   Else
  312.     Function Return False
  313.   EndIf
  314. End Function
  315.  
  316. Function.b InitLand{FName$,PalNum.w,WidthClip.l,HeightClip.l}
  317. ;Initialise land
  318.   SHARED LandBase.l,LandBase2.l,LandWidth.l,LandHeight.l,HeightMultiplier.l,HeightAdder.l
  319.   SHARED LandBuffer.l,LandBuffer2.l,PrefDisplayWidth,GlobalTemp,PrefDisplayHeight,ILBMActualHeight.l
  320.   If Exists(FName$)
  321.     suc=OpenFile(#ILBM_FileHandle,FName$)
  322.     If suc=False Then Function Return False
  323.   Else
  324.     Function Return False
  325.   EndIf
  326.   FormCheck.l=0
  327.   ReadMem #ILBM_FileHandle,&FormCheck,4
  328.   If FormCheck<>#FORMid Then Function Return False
  329.   TempLong.l=0
  330.   ReadMem #ILBM_FileHandle,&TempLong,4
  331.   ReadMem #ILBM_FileHandle,&TempLong,4
  332.   CloseFile #ILBM_FileHandle
  333.   If TempLong<>#ILBMid Then Function Return False
  334.   ILBMInfo FName$
  335.   If WidthClip=0 Then WidthClip=ILBMWidth
  336.   If HeightClip=0 Then HeightClip=ILBMHeight
  337.   Width.l=Min(WidthClip,ILBMWidth)
  338.   If Width>(Width AND $FFFFFFF0) Then Width=(Width+16) AND $FFFFFFF0 ; Handle non-aligned widths (nearest 4 pixels)
  339.   Height.l=Min(HeightClip,ILBMHeight)
  340.   If Height<PrefDisplayHeight Then YOff=PrefDisplayHeight-Height Else YOff=0
  341.   LandWidth.l=Max(Width,PrefDisplayWidth) ; Total viewable game environment width
  342.   LandHeight.l=Max(PrefDisplayHeight,(Height*HeightMultiplier)+HeightAdder) ; Total viewable game environment height
  343.   ILBMActualHeight.l=Height ; Height of actual IFF image, for copy purposes
  344.   Height=Max(Height,PrefDisplayHeight)
  345.   If AvailMem_(#MEMF_FAST)<(LandWidth*LandHeight)+16 Then Function Return False
  346.   LandBase.l=MBitmap(0,LandWidth,LandHeight)
  347.   LandBuffer.l=LandBase
  348.   If AvailMem_(#MEMF_FAST)<(LandWidth*LandHeight)+16 Then Function Return False
  349.   LandBase2.l=MBitmap(1,LandWidth,LandHeight)
  350.   LandBuffer2.l=LandBase2
  351.   LandOff.l=((LandHeight-Height)*LandWidth)+(YOff*LandWidth)
  352.   success=LoadLandILBM{FName$,PalNum,Width,Height,LandBuffer+LandOff,0}
  353.   Function Return success
  354. End Function
  355.  
  356.